#!/usr/bin/env python
# -*- coding: utf-8 -*-


import os
import glob
from core.module_interfaces import CLI
from core.utils.log import logger
from core.utils.tests import init_test_info, read_conf
name = 'list'


class List(CLI):
    def configure(self, parser):
        lparser = parser.add_parser(name, help='list test configurations')
        lparser.set_defaults(subcommand=name.lower())
        group = lparser.add_mutually_exclusive_group()
        group.add_argument(
            'test-suite',
            nargs='*',
            default=[],
            help="show avalible test suites and type")
        group.add_argument(
            '--functional',
            action='store_true',
            help="show funcitonal test suites")
        group.add_argument(
            '--performance',
            action='store_true',
            help="show performance test suites")
        group.add_argument(
            '--stress',
            action='store_true',
            help="show stress test suites")

        logger.debug("List: CLI configure")

    def run(self, config):
        logger.debug("List: CLI run")
        for suite in config.test_list:
            testconf = init_test_info(suite, config)
            if not os.path.exists(testconf.conf_path):
                logger.error(
                    "There is no configuration {} for test {}".
                    format(testconf.conf_path, suite))
                continue
            _, iv, fields = read_conf(testconf.conf_path, suite)
            logger.debug("Should list {}".format(suite))
            output = []
            recorder = []
            recorder.extend([field for field in fields if field != 'testconf'])
            recorder.append('testconf')
            output.append(recorder)
            fieldwidth = {}
            nfields = []
            for field in fields:
                fieldwidth[field] = len(field)
                if field == 'testconf':
                    continue
                nfields.append(field)
            if 'testconf' not in fieldwidth:
                fieldwidth['testconf'] = 8
            nfields.append('testconf')

            for index, data in enumerate(iv):
                recorder = []
                for field in fields:
                    if len(data[field]) > fieldwidth[field]:
                        fieldwidth[field] = len(data[field])
                    if field == 'testconf':
                        continue
                    recorder.append(data[field])
                recorder.append(data['testconf'])
                output.append(recorder)
            for data in output:
                print(" ".join(
                    [str(data[i]).ljust(fieldwidth[field])
                     for i, field in enumerate(nfields)]
                ))

        if not config.test_list:
            category = self._check_test_suite_category(config.parser)
            dirs = os.path.realpath(__file__).split(os.path.sep)
            rootpath = os.path.join('/', *dirs[:-5])
            confpath = os.path.join(rootpath, 'conf')
            testspath = os.path.join(rootpath, 'tests')
            if category:
                conffiles = glob.glob(
                    os.path.join(confpath, category, '*'))
            else:
                conffiles = glob.glob(os.path.join(confpath, '*', '*'))
            avaliable_tests = []
            for conffile in conffiles:
                item = {
                    'name': "",
                    'type': "",
                }
                confname = os.path.basename(conffile)
                confname = os.path.splitext(confname)[0]
                testpath = os.path.join(testspath, confname)
                if os.path.isdir(testpath):
                    item['name'] = confname
                    if category:
                        item['type'] = category
                    else:
                        tmp = os.path.dirname(conffile)
                        item['type'] = os.path.basename(tmp)
                    avaliable_tests.append(item)
            if avaliable_tests:
                for test in avaliable_tests:
                    print("{} {}".format(
                        test['name'].ljust(50),
                        test['type'].ljust(50)))
            else:
                logger.error("No avalible test suite found!")
                logger.error("Please put test suit to: {}".format(testspath))

    def _check_test_suite_category(self, options):
        """
        Check options and return test-suite category
        posible value: functional, performance, stress, None
        """
        posible_category = [
            'functional',
            'performance',
            'stress',
        ]
        for category in posible_category:
            if options[category]:
                return category
        return None
